package com.yu8home.asyc;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.yu8home.asyc.lis.LogEvent;
import com.yu8home.asyc.service.AaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class AsycController {
    @Autowired
    public AaService aaService;

    @GetMapping("/a")
    public String a() {
        aaService.a();

        log.info("==================1==================");
        AsycController asycController = SpringUtil.getBean(AsycController.class);
        asycController.n();
        log.info("==================2==================");

        LogEvent logEvent = new LogEvent();
        logEvent.setName("yu8home.aaaa");
        SpringUtil.getApplicationContext().publishEvent(logEvent);

        log.info("AsycController.a");
        return "success！";
    }

    @Async
    public void n() {
        log.info("AsycController.n...");
        ThreadUtil.sleep(3 * 1000);
        log.info("AsycController.n!!!");
    }

    // get() 方法的异常处理较为繁琐，需要捕获InterruptedException和ExecutionException异常，并进行相应的处理。因此在 Lambda 表达式或流式操作中，推荐使用join() 方法
    @GetMapping("/b")
    public String testCompletableFutureTask() {
        long l = System.currentTimeMillis();

        List<String> words = Arrays.asList("F", "T", "S", "Z", "J", "C");

        List<CompletableFuture<List<String>>> completableFutureList = words.stream().map(word -> aaService.completableFutureTask(word)).collect(Collectors.toList());
        List<List<String>> results = completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList());

        System.out.println(System.currentTimeMillis() - l);
        return results.toString();
    }

}
